package gui;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

import calculate.LeastSquare;

/**
 * This class implements the GUI of the Least Square Method
 * 
 * @author Jacky Xu
 *
 */
public class LeastSquareGUI {

	private JFrame frame;
	private boolean lockdown = false;
	private Font font = new Font("宋体", Font.BOLD, 30);

	/**
	 * This method initialize the GUI of the LSM
	 * 
	 */
	public LeastSquareGUI() {
		LeastSquare algorithm = new LeastSquare();
		List<Double> x = new ArrayList<Double>();
		List<Double> y = new ArrayList<Double>();

		frame = new JFrame("LeastSquare");
		frame.setVisible(true);
		frame.setBounds(700, 350, 550, 350);

		GridBagLayout gbaglayout = new GridBagLayout(); // GridBagLayout
		GridBagConstraints constraints = new GridBagConstraints();
		frame.setLayout(gbaglayout);

		constraints.fill = GridBagConstraints.BOTH;
		constraints.weightx = 0.0;
		constraints.gridwidth = GridBagConstraints.REMAINDER;

		JLabel label1 = new JLabel("X:");
		label1.setFont(font);
		label1.setHorizontalTextPosition(JLabel.RIGHT);
		setConstrain(constraints, 0, 0, 1, 1, 0.02, 0.02);
		gbaglayout.setConstraints(label1, constraints);
		frame.add(label1);

		JTextField line1 = new JTextField();
		line1.setHorizontalAlignment(JTextField.RIGHT);
		line1.setFont(font);
		setConstrain(constraints, 1, 0, 2, 1, 0.5, 0.5);
		gbaglayout.setConstraints(line1, constraints);
		frame.add(line1);

		JLabel label2 = new JLabel("Y:");
		label2.setFont(font);
		label2.setHorizontalTextPosition(JLabel.RIGHT);
		setConstrain(constraints, 0, 1, 1, 1, 0.02, 0.02);
		gbaglayout.setConstraints(label2, constraints);
		frame.add(label2);

		JTextField line2 = new JTextField();
		line2.setHorizontalAlignment(JTextField.RIGHT);
		line2.setFont(font);
		setConstrain(constraints, 1, 1, 2, 1, 0.5, 0.5);
		gbaglayout.setConstraints(line2, constraints);
		frame.add(line2);

		JLabel label3 = new JLabel("Result:");
		label3.setFont(font);
		label3.setHorizontalTextPosition(JLabel.RIGHT);
		setConstrain(constraints, 0, 2, 1, 1, 0.02, 0.02);
		gbaglayout.setConstraints(label3, constraints);
		frame.add(label3);

		JTextField line3 = new JTextField();
		line3.setHorizontalAlignment(JTextField.RIGHT);
		line3.setFont(font);
		line3.setEditable(false);
		setConstrain(constraints, 1, 2, 2, 1, 0.5, 0.5);
		gbaglayout.setConstraints(line3, constraints);
		frame.add(line3);

		JButton button1 = new JButton("Enter");
		button1.setFont(font);
		button1.addActionListener(e -> {
			if (this.lockdown) {
				return;
			}
			String buffer1 = line1.getText();
			String buffer2 = line2.getText();
			try {
				line1.setText("");
				line2.setText("");
				if (!buffer1.equals("") && !buffer2.equals("")) {
					double x_temp = Double.valueOf(buffer1);
					double y_temp = Double.valueOf(buffer2);

					x.add(x_temp);
					y.add(y_temp);
				}

			} catch (NumberFormatException e1) {

			}
		});
		setConstrain(constraints, 0, 3, 1, 1, 1, 1);
		gbaglayout.setConstraints(button1, constraints);
		frame.add(button1);

		JButton button2 = new JButton("Restart");
		button2.setFont(font);
		button2.addActionListener(e -> {
			line1.setEditable(true);
			line1.setText("");
			line2.setEditable(true);
			line2.setText("");
			line3.setText("");
			x.clear();
			y.clear();
			this.lockdown = false;
		});
		setConstrain(constraints, 1, 3, 1, 1, 1, 1);
		gbaglayout.setConstraints(button2, constraints);
		frame.add(button2);

		JButton button3 = new JButton("Least Square");
		button3.setFont(font);
		button3.addActionListener(e -> {
			if (this.lockdown) {
				return;
			}

			if (x.size() <= 1 || y.size() <= 1) {
				line3.setText("Error!");
				this.lockdown = true;
				line1.setEditable(false);
				line2.setEditable(false);
				return;
			}

			List<Double> ret = algorithm.LS(x, y);
			String output;
			if (ret.get(1) >= 0) {
				output = "y = " + String.format("%.2f", ret.get(0)) + " x + " + String.format("%.2f", ret.get(1));
			} else {
				output = "y = " + String.format("%.2f", ret.get(0)) + " x - " + String.format("%.2f", -ret.get(1));
			}
			line1.setText("");
			line2.setText("");
			line3.setText(output);

			this.lockdown = true;
			line1.setEditable(false);
			line2.setEditable(false);

		});
		setConstrain(constraints, 2, 3, 1, 1, 1, 1);
		gbaglayout.setConstraints(button3, constraints);
		frame.add(button3);

	}

	private void setConstrain(GridBagConstraints constrains, int gridx, int gridy, int gridwidth, int gridheight,
			double weightx, double weighty) {
		constrains.gridx = gridx;
		constrains.gridy = gridy;
		constrains.gridwidth = gridwidth;
		constrains.gridheight = gridheight;
		constrains.weightx = weightx;
		constrains.weighty = weighty;
	}
}
